﻿@using System.Reflection
@using AntDesign.TableModels
@inherits BaseComponent
@typeparam TItem where TItem : class, new()

<Table TItem="TItem" Size="TableSize.Small" Responsive Resizable="Model.Resizable"
       ScrollX="@Model.FixedWidth" ScrollY="@Model.FixedHeight" ScrollBarWidth="8px"
       DataSource="Model.Result.PageData" Total="Model.Result.TotalCount"
       @bind-PageIndex="Model.Criteria.PageIndex"
       @bind-PageSize="Model.Criteria.PageSize"
       @bind-SelectedRows="Model.SelectedRows"
       RowKey="Model.RowKey" OnChange="OnChange" OnRowClick="OnRowClick"
       HidePagination="!Model.ShowPager" PaginationPosition="bottomRight">
    <ChildContent>
        @if (!string.IsNullOrWhiteSpace(Model.SelectType))
        {
            <Selection Type="@Model.SelectType" Width="50" />
        }
        <AntGenerateColumns Table="Model" Item="context" />
        @if (Model.HasAction)
        {
            var actions = Model.RowActions?.Invoke(context);
            if (actions == null)
                actions = Model.Actions;
            <ActionColumn Title="@Language["Title.Action"]" Width="140">
                @if (actions.Count > 2)
                {
                    var first = actions[0];
                    var firstName = Language.GetString(first);
                    var mores = actions.Skip(1).ToList();
                    <Tag Color="@GetActionColor(first.Style)" OnClick="e=>Model.OnAction?.Invoke(first, context)">@firstName</Tag>
                    <AntDropdown Context="Context" Text="@Language["Button.More"]" Items="mores" OnItemClick="e=>Model.OnAction?.Invoke(e, context)" />
                }
                else
                {
                    foreach (var item in actions)
                    {
                        var itemName = Language.GetString(item);
                        <Tag Color="@GetActionColor(item.Style)" OnClick="e=>Model.OnAction?.Invoke(item, context)">@itemName</Tag>
                    }
                }
            </ActionColumn>
        }
    </ChildContent>
    <PaginationTemplate>
        <Pagination Class="@context.PaginationClass"
                    Total="context.Total" PageSize="context.PageSize" Current="context.PageIndex"
                    ShowTotal="showTotal" ShowSizeChanger ShowQuickJumper
                    OnChange="context.HandlePageChange" />
     </PaginationTemplate>
 </Table>

 @code {
    private string GetActionColor(string style) => style == "danger" ? "red-inverse" : "blue-inverse";
    private Func<PaginationTotalContext, string> showTotal => ctx => Context.Language["Page.Total"].Replace("{total}", $"{ctx.Total}");

    [Parameter] public TableModel<TItem> Model { get; set; }

    protected override void OnInitialized()
    {
        Model.OnRefresh = RefreshAsync;
        base.OnInitialized();
    }

    public async Task RefreshAsync()
    {
        Model.Result = await Model.OnQuery?.Invoke(Model.Criteria);
        StateHasChanged();
    }

    private async Task OnChange(QueryModel<TItem> queryModel)
    {
        if (Model.OnQuery == null)
            return;

        //页码
        Model.Criteria.PageIndex = queryModel.PageIndex;
        Model.Criteria.PageSize = queryModel.PageSize;
        //TODO：表格筛选
        // Model.Criteria.Query.Clear();
        // foreach (var item in queryModel.FilterModel)
        // {
        //     foreach (var filter in item.Filters)
        //     {
        //         var type = GetQueryType(filter.FilterCompareOperator);
        //         Model.Criteria.SetQuery(item.FieldName, type, $"{filter.Value}");
        //     }
        // }
        //排序
        var sorts = queryModel.SortModel.Where(s => !string.IsNullOrWhiteSpace(s.Sort));
        Model.Criteria.OrderBys = sorts.Select(m => GetOrderBy(m)).ToArray();
        Model.Result = await Model.OnQuery?.Invoke(Model.Criteria);
    }

    private async void OnRowClick(RowData<TItem> row)
    {
        if (Model.OnRowClick == null)
            return;

        await Model.OnRowClick.Invoke(row.Data);
    }

    private QueryType GetQueryType(TableFilterCompareOperator tableFilter)
    {
        switch (tableFilter)
        {
            case TableFilterCompareOperator.Equals:
                return QueryType.Equal;
            case TableFilterCompareOperator.Contains:
                return QueryType.Contain;
            case TableFilterCompareOperator.StartsWith:
                return QueryType.StartWith;
            case TableFilterCompareOperator.EndsWith:
                return QueryType.EndWith;
            case TableFilterCompareOperator.GreaterThan:
                return QueryType.GreatThan;
            case TableFilterCompareOperator.LessThan:
                return QueryType.LessThan;
            case TableFilterCompareOperator.GreaterThanOrEquals:
                return QueryType.GreatEqual;
            case TableFilterCompareOperator.LessThanOrEquals:
                return QueryType.LessEqual;
            case TableFilterCompareOperator.Condition:
                return QueryType.Batch;
            case TableFilterCompareOperator.NotEquals:
                return QueryType.NotEqual;
            case TableFilterCompareOperator.IsNull:
                return QueryType.Equal;
            case TableFilterCompareOperator.IsNotNull:
                return QueryType.NotEqual;
            case TableFilterCompareOperator.NotContains:
                return QueryType.NotEqual;
            case TableFilterCompareOperator.TheSameDateWith:
                return QueryType.Between;
            default:
                return QueryType.Contain;
        }
    }

    private string GetOrderBy(ITableSortModel model)
    {
        //descend  ascend
        var sort = model.Sort == "descend" ? "desc" : "asc";
        return $"{model.FieldName} {sort}";
    }
}